package com.weiiew.calculationService.craft;

import lombok.Data;

import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.function.BiConsumer;


/**
 * @Description
 * @Author 魏锴
 * @Date 2025/3/16
 */
@Data
public class ItemChangeRecord {

    @Data
    public static class NodeInfo {
        private double amount;
        private final String nodeId;

        public NodeInfo(double amount, String nodeId) {
            this.amount = amount;
            this.nodeId = nodeId;
        }
    }

    // 使用 LinkedList 支持高效头部删除
    private final Map<Integer, Deque<NodeInfo>> storage = new HashMap<>();

    /**
     * 优化后的物品变化记录方法
     * @param itemId 物品ID
     * @param delta 数量变化（可正可负）
     * @param nodeId 节点ID
     * @param nodeConsumer 节点处理回调（如构建连接）
     */
    public void recordChange(int itemId, double delta, String nodeId, BiConsumer<String, String> nodeConsumer) {
//        System.out.println(String.format("recordChange执行参数 %d %d %d", itemId, delta, prefix));
        Deque<NodeInfo> nodes = storage.computeIfAbsent(itemId, k -> new LinkedList<>());
        // 处理剩余未抵消的 delta
        while (delta != 0 && !nodes.isEmpty()) {
            NodeInfo first = nodes.peekFirst();
            if (isOppositeSign(first.amount, delta)) {
                delta = processOppositeSign(nodeId, first, delta, nodeConsumer, nodes);
            } else {
                break; // 同号时停止抵消
            }
        }
        // 剩余 delta 需要记录
        if (delta != 0) {
            nodes.addLast(new NodeInfo(delta, nodeId));
        }
        // 清理空记录
        if (nodes.isEmpty()) {
            storage.remove(itemId);
        }
    }

    // 判断两个值是否异号
    private boolean isOppositeSign(double a, double b) {
        return a * b < 0;
    }

    // 处理异号抵消逻辑
    private double processOppositeSign(String nodeId, NodeInfo existing, double delta,
                                       BiConsumer<String, String> consumer, Deque<NodeInfo> nodes) {
        double total = existing.amount + delta;

        if (existing.amount > 0 && delta < 0) consumer.accept(nodeId, existing.nodeId);
        else consumer.accept(existing.nodeId, nodeId);

        if (Math.abs(total) < 1e-9) { // 完全抵消
            nodes.removeFirst();
            return 0;
        } else if (total * existing.amount > 0) {
            // 原节点剩余部分
            existing.amount = total;
            return 0;
        } else {
            // 新 delta 剩余部分
            nodes.removeFirst();
            return total;
        }
    }
}